package zx.lrn.notes.basic_data_type;

/**
 * 码点学习
 * JAVA中的String是Unicode字符序列，用char[]表示，每一个char占16bit，一个char用来表示一个unicode字符编码
 * 由于历史原因，JAVA设计时采用了16位的Unicode字符编码，16位能够表示的最大字符数为65535，但当Unicode加入了更多国家的语言后， 16bit就不够用了，一部分字符就需要用32bit进行编码；
 *
 * unicode进行扩展的方式为：将那些16bit放不下的字符称为辅助字符，辅助字符的编码采用32bit，以16bit分为两部分；将16bit能表示的所有数字中的
 * 一小部分（D800-DBFF）划出，不表示任何字符，只用作占32bit的辅助字符的第一部分专用；这样，拿到一个unicode编码后，立刻就知道它是单独表示 一个字符还是表示一个辅助字符的第一部分；
 *
 * 基于上述事实，用char来表示一个字符串中的每个元素是不精确的，当字符串中出现辅助字符后，char是容纳不下的。 例：𝕆（八元数集）是一个辅助字符; "𝕆".length=2; "𝕆".charAt(0) != 𝕆;
 * 精确的表示需要用到码点（codePoint），每个码点用来表示一个字符，码点的类型是int(32bit)；
 *
 * 所以Core JAVA不建议使用char
 */
public class CodePoint {

    public static void main(String[] args) {
        String string = "12𝕆45";
        System.out.println(string.length()); // char的数量为6
        System.out.println(string.codePoints().toArray().length); // 码点的数量为5
        // 输出每个码点
        string.codePoints().forEach(System.out::println);
        // 遍历字符串的每个码点，将每个码点转成字符串
        string.codePoints().forEach(cp -> System.out.println(new String(new int[] {cp}, 0, 1)));
        // String转码点
        int[] cpArray = string.codePoints().toArray();
        // 码点转String
        System.out.println(new String(cpArray, 0, cpArray.length));

        // 使用StringBuilder整合CodePoint
        StringBuilder sb = new StringBuilder();
        sb.appendCodePoint(49); // 1的码点
        sb.appendCodePoint(120134); // 𝕆的码点
        System.out.println(sb);
    }
}
